package cn.org.timespace.plat.socket.mina.server;

import java.net.InetSocketAddress;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.SocketSessionConfig;

import cn.org.timespace.ons.util.StringUtil;
import cn.org.timespace.plat.socket.mina.filter.ESPlatProtocalPack;
import cn.org.timespace.plat.socket.mina.filter.command.AbstractESPlatCommand;
import cn.org.timespace.plat.socket.mina.filter.command.ESPlatCommandFactory;
import cn.org.timespace.plat.socket.util.MinaPlatUtil;

public class ESPlatServerHandler extends IoHandlerAdapter {

	private final static Log log = LogFactory.getLog(ESPlatServerHandler.class);
	
	/**
	 * 当会话创建时被触发
	 */
	@Override
	public void sessionCreated(IoSession session) {
	}
	
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		
		String ipPort = MinaPlatUtil.getIpPort((InetSocketAddress)session.getRemoteAddress());
		session.setAttribute("ipPort", ipPort);
		log.info("sessionOpened：" + ipPort); 
		
		SocketSessionConfig cfg = (SocketSessionConfig) session.getConfig();  
		cfg.setReceiveBufferSize(2048);
        cfg.setKeepAlive(true);  
        cfg.setTcpNoDelay(true);  	// 设置为非延迟发送，为true则不组装成大包发送，收到东西马上发出
        cfg.setSoLinger(0); 		// 在调用了close()方法后，不会再进入TIME_WAIT状态，而是直接Close掉
        
//        ProcessPackage.jmsSendTest(ipPort + "建立连接");
	}
	
	@Override
	public void sessionClosed(IoSession iosession) throws Exception {
		String ipPort = (String) iosession.getAttribute("ipPort");
		if(StringUtil.notNull(ipPort)) {
			log.info("sessionClosed：" + ipPort);
//			ProcessPackage.jmsSendTest(ipPort + "断开连接");
			
			String machineNo = (String)iosession.getAttribute("MachineNo");
			if(StringUtil.notNull(machineNo)) {
				//记录硬件中端断开的状态和记录
//				ProcessPackage.saveMachineNo(iosession, "close");
			}
		}
	}

	/**
	 * 当接收到消息后被触发
	 */
	@Override
	public void messageReceived(IoSession session, Object message) {
		if(message instanceof ESPlatProtocalPack) {
			
			MinaPlatUtil.synSession(session);
			
			ESPlatProtocalPack pack = (ESPlatProtocalPack) message;
			log.debug("接收的信息为：" + pack.toString()); 
			
			//是否为第一次连接
			boolean isFirstConnect = false;
			
			String machineNo = (String) session.getAttribute("MachineNo");
			if(StringUtil.isNull(machineNo)) {
				machineNo = pack.getMachineNo();
				session.setAttribute("MachineNo", machineNo);
				
				isFirstConnect = true;
			}
			
			//首次连接执行
//			if(isFirstConnect) {
//				//记录硬件终端首次连接的状态和记录
//				ProcessPackage.saveMachineNo(session, "connect");
//			}
			
			AbstractESPlatCommand command = ESPlatCommandFactory.newCommand(pack.getFunctionNo());
			if(command != null) {
				command.processPackage(session, pack);
			}
//			else {
//				ProcessPackage.addRecord(pack, "error", false, (String)session.getAttribute("ipPort"));
//			}
			
			//首次连接执行
//			if(isFirstConnect) {
//				//将配置信息同步到信息机
//				if("true".equals(SocketJMSPropertie.getProperty("sync.machine", "false"))) {
//					ProcessPackage.sync(machineNo, session);
//				}
//			}
		}
		else {
			log.error("类型错误，丢弃消息");
		}
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		String ipPort = MinaPlatUtil.getIpPort((InetSocketAddress)session.getRemoteAddress());
		String machineNo = (String) session.getAttribute("MachineNo");
		
		log.error("会话发生异常(" + ipPort + "," + machineNo + "):" + cause);
		cause.printStackTrace();
	}
	
	@Override
	public void sessionIdle(IoSession session, IdleStatus idlestatus) throws Exception {
		//超过设定的空闲时间，就断开session
		session.setAttribute("closeFlag", "1");//异常关闭
		session.close(true);
	}
}
